package com.sinodata.bsm.cicp.collector.sqlserver;

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.AbstractJDBCCollector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.DBConnectionUtil;
import com.sinodata.bsm.common.constants.SeparatorConstants;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class Security extends AbstractJDBCCollector {
    private static final Logger logger = Logger.getLogger(Security.class);

    // private static final int DEADLOCK_WAIT_TIME = 60;

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        try {
            String[] propMetas = getPropMeta();
            //        String serverName = this.getParamMap().get("服务器名");
            String serverName = this.getParamMap().get("ServerName");

            String sql = "sp_helplogins";
            String[] rs = this.getStrings(serverName, sql, ip);

            ResPropertyValue propertyValueX = new ResPropertyValue();
            ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
            for (int i = 0; i < propMetas.length; i++) {
                propValues[i] = ResPropertyValue.createPropValue(rs[i], propMetas[i]);
            }

            propertyValueX.setValues(propValues);
            values.add(propertyValueX);
        } catch (Exception e) {
            logger.error("failed to collect sqlserver security", e);

            throw new CollectorException(e);
        }
        return values;
    }

    private String[] getStrings(String serverName, String sql, String ip) throws CollectorException {
        String[] propValArr = new String[2];

        CallableStatement cstmt = null;
        ResultSet rst = null;
        Connection conn = null;
        try {
            conn = DBConnectionUtil.getInstance().getConnection("sqlserver", ip, serverName);
            if (conn == null) {
                return null;
            }
            StringBuffer loginDetail = new StringBuffer();
            StringBuffer loginUserDetail = new StringBuffer();
            cstmt = conn.prepareCall(sql);
            rst = cstmt.executeQuery();
            // 登录名,默认数据库,默认语言,是否有相关用户,是否远程;
            //            loginDetail.append("Login Name").append(SeparatorConstants.COL_SEPARATOR);//登录名
            //            loginDetail.append("Default Database").append(SeparatorConstants.COL_SEPARATOR);//默认数据库
            //            loginDetail.append("Default Language").append(SeparatorConstants.COL_SEPARATOR);//默认语言
            //            loginDetail.append("Whether Exist a related users").append(SeparatorConstants.COL_SEPARATOR);//是否有相关用户
            //            loginDetail.append("Whether Remote").append(SeparatorConstants.COL_SEPARATOR);//是否远程
            //            loginDetail.append(SeparatorConstants.LIN_SEPARATOR);
            // 登录名,默认数据库,用户/角色名称,用户/角色
            //            loginUserDetail.append("Login Name").append(SeparatorConstants.COL_SEPARATOR);//登录名
            //            loginUserDetail.append("Default Database").append(SeparatorConstants.COL_SEPARATOR);//默认数据库
            //            loginUserDetail.append("User/Role Name").append(SeparatorConstants.COL_SEPARATOR);//用户/角色名称
            //            loginUserDetail.append("User/Role").append(SeparatorConstants.COL_SEPARATOR);//用户/角色
            //            loginUserDetail.append(SeparatorConstants.LIN_SEPARATOR);

            // login detail
            if (rst != null) {
                while (rst.next()) {
                    String line = getLoginTabLineStr(rst);
                    loginDetail.append(line).append(SeparatorConstants.LIN_SEPARATOR);
                }
            }
            String loginDetailstr = loginDetail.toString();

            cstmt.getMoreResults();
            rst = cstmt.getResultSet();

            if (rst != null) {
                while (rst.next()) {
                    String line = getLoginUserTabLineStr(rst);
                    loginUserDetail.append(line).append(SeparatorConstants.LIN_SEPARATOR);
                }
            }
            String loginUserDetailstr = loginUserDetail.toString();

            propValArr[0] = "" + loginDetailstr;
            propValArr[1] = "" + loginUserDetailstr;
            return propValArr;
        } catch (SQLException sqle) {
            logger.error("Collecting sqlserver login information", sqle);
            throw new CollectorException(sqle);
        } catch (IOException ioex) {
            logger.error("Collecting sqlserver login information", ioex);
            throw new CollectorException(ioex);
        } finally {
            try {
                if (rst != null)
                    rst.close();
                if (cstmt != null)
                    cstmt.close();
            } catch (SQLException e) {
                logger.error("failed to close database", e);
                throw new CollectorException(e);
            }
            DBConnectionUtil.getInstance().returnConnection(conn);
        }
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "ServerName" };
    }

    @Override
    public String[] getPropMeta() {
        //        return new String[] { "登录帐户列表", "登录帐户相关用户信息" };
        return new String[] { "LoginAccountList", "LoginUserRelatedInfo" };
    }

    private String getLoginTabLineStr(ResultSet rst) throws CollectorException {
        StringBuffer tabLineStr = new StringBuffer();
        int colNum = 6;
        try {
            for (int i = 1; i <= colNum; i++) {
                if (i == 2)
                    continue;
                String val = rst.getString(i);
                if (val == null || val.trim().length() == 0) {
                    val = " ";
                } else
                    val = val.trim();
                tabLineStr.append(val).append(SeparatorConstants.COL_SEPARATOR);
            }
        } catch (Exception e) {
            logger.error("failed to get login TabLineStr", e);
            throw new CollectorException(e);
        }
        return tabLineStr.toString();
    }

    private String getLoginUserTabLineStr(ResultSet rst) throws CollectorException {
        StringBuffer tabLineStr = new StringBuffer();
        int colNum = 4;
        try {
            for (int i = 1; i <= colNum; i++) {
                String val = rst.getString(i);
                if (val == null || val.trim().length() == 0) {
                    val = " ";
                } else
                    val = val.trim();
                if (i == 4) {
                    if (val.equals("MemberOf"))
                        val = "ROLE";
                    else if (val.equals("User"))
                        val = "USER";
                }
                tabLineStr.append(val).append(SeparatorConstants.COL_SEPARATOR);
            }
        } catch (Exception e) {
            logger.error("failed to get login user TabLineStr", e);
            throw new CollectorException(e);
        }
        return tabLineStr.toString();
    }
}
